const Koa = require("koa");
const KoaRouter = require("koa-router");
const bodyparser = require("koa-bodyparser");
const { query } = require("./mysql");
const { genToken } = require("./util");
const auth = require("./middleware/auth.js");

const app = new Koa();
const router = new KoaRouter();

// RESTful 规范、HTTP 响应码
// 添加新地址
router.post("/addresses", async (ctx) => {
    // 解析请求头的信息
    // const { token } = ctx.headers;

    // let user;
    // // 解析 token
    // try {
    //     // 解析成功后，就会返回 token 中保存的用户信息
    //     user = checkToken(token);
    // } catch (error) {
    //     // token 过期错误
    //     if (error.name === "TokenExpiredError") {
    //         ctx.body = {
    //             code: 401,
    //             message: "token过期了",
    //         };
    //         return;
    //     }

    //     // token 篡改
    //     if (error.name === "JsonWebTokenError") {
    //         ctx.body = {
    //             code: 401,
    //             message: "token不合法",
    //         };
    //         return;
    //     }

    //     ctx.body = {
    //         code: 401,
    //         message: "token解析失败",
    //     };
    // }

    // 解析请求体数据
    const { username, mobile, address, is_default } = ctx.request.body;
    // 非空校验
    if (!username || !mobile || !address || is_default === undefined) {
        ctx.body = {
            code: 400,
            message: "缺少必须参数",
        };
        return;
    }
    // 手机号校验
    if (!/^1[35789]\d{9}$/.test(mobile)) {
        ctx.body = {
            code: 400,
            message: "手机号格式不正确",
        };
        return;
    }
    // 是否默认
    if (isNaN(is_default) || ![0, 1].includes(Number(is_default))) {
        ctx.body = {
            code: 400,
            message: "默认地址参数不正确",
        };
        return;
    }

    // 用户存不存在
    // let res = await query("select * from user where id = ?", [uid]);
    // if (res.length === 0) {
    //     ctx.body = {
    //         code: 404,
    //         message: "用户不存在",
    //     };
    //     return;
    // }

    console.log(ctx.user);

    // 如果有默认地址了，是不是得重置为非默认
    if (Number(is_default) === 1) {
        await query(
            "update address set is_default = 0 where is_default = 1 and uid = ?",
            [ctx.user.id]
        );
    }

    // 添加新地址记录
    res = await query(
        "insert into address (username, mobile, address, is_default, uid) values (?, ?, ?, ?, ?)",
        [username, mobile, address, is_default, ctx.user.id]
    );

    // 插入成功
    if (res.affectedRows === 1) {
        ctx.body = {
            code: 201,
            message: "添加成功",
        };
    }
});

// 获取地址列表
router.get("/addresses", async (ctx) => {
    // 分页
    let { pagenum, pagesize } = ctx.query;

    // 校验分页参数
    if (isNaN(pagenum) || isNaN(pagesize)) {
        const res = await query("select * from address where uid = ?", [
            ctx.user.id,
        ]);
        ctx.body = {
            code: 200,
            data: res,
            message: "查询成功",
        };
        return;
    }

    // 分页参数
    pagenum = Number(pagenum);
    pagesize = Number(pagesize);
    // 使用 SQL 的 limit 语句，limit startIndex, 10
    const startIndex = (pagenum - 1) * pagesize;

    // 分页内容
    let list = await query(
        "select * from address where uid = ? order by is_default desc limit ?, ?",
        [ctx.user.id, startIndex, pagesize]
    );

    // 计数
    let res = await query(
        "select count(*) as total from address where uid = ?",
        [ctx.user.id]
    );
    const total = res[0]["total"];

    ctx.body = {
        code: 200,
        data: {
            list,
            total,
        },
        message: "获取列表成功",
    };

    // 解析请求头中的 token
    // const token = ctx.headers.token;

    // let user;
    // // 解析 token
    // try {
    //     // 解析成功后，就会返回 token 中保存的用户信息
    //     user = checkToken(token);
    // } catch (error) {
    //     // token 过期错误
    //     if (error.name === "TokenExpiredError") {
    //         ctx.body = {
    //             code: 401,
    //             message: "token过期了",
    //         };
    //         return;
    //     }

    //     // token 篡改
    //     if (error.name === "JsonWebTokenError") {
    //         ctx.body = {
    //             code: 401,
    //             message: "token不合法",
    //         };
    //         return;
    //     }

    //     ctx.body = {
    //         code: 401,
    //         message: "token解析失败",
    //     };
    // }

    // 直接从数据库中查询所有地址
    // const res = await query("select * from address where uid = ?", [
    // ctx.headers.uid,
    // user.id,
    // ctx.user.id,
    // ]);
});

// 修改
router.put("/addresses/:id/default", async (ctx) => {
    // 接收路径参数
    const { id } = ctx.params;
    // 接收请求参数
    const { is_default } = ctx.request.body;
    // 校验参数
    if (isNaN(is_default) || ![0, 1].includes(Number(is_default))) {
        ctx.body = {
            code: 400,
            message: "默认地址参数不正确",
        };
        return;
    }
    // 不可以修改其他用户的地址
    const addresses = await query("select * from address where id = ?", [id]);
    if (addresses.length === 0) {
        ctx.body = {
            code: 404,
            message: "地址记录不存在",
        };
        return;
    }
    const address = addresses[0];
    // 是不是当前用户的地址
    if (ctx.user.id !== address.uid) {
        ctx.body = {
            code: 403,
            message: "这不是你的地址",
        };
        return;
    }
    // 清除以前的默认地址
    await query(
        "update address set is_default = 0 where is_default = 1 and uid = ?",
        ctx.user.id
    );
    // 修改
    const res = await query("update address set is_default = ? where id = ?", [
        is_default,
        id,
    ]);
    // 判断是否修改成功
    if (res.affectedRows === 1) {
        ctx.body = {
            code: 200,
            message: "修改成功",
        };
    }
});

// 注册(业务)
// 添加用户 (功能)
router.post("/register", async (ctx) => {
    // 解构参数
    const { username, password, nickname } = ctx.request.body;

    // 非空校验
    if (!username || !password || !nickname) {
        ctx.body = {
            code: 400,
            message: "缺少必须参数",
        };
        return;
    }

    // 保证账号唯一
    const users = await query("select * from user where username = ?", [
        username,
    ]);

    if (users.length !== 0) {
        ctx.body = {
            code: 403,
            message: "该用户已存在",
        };
        return;
    }

    // 注册
    const res = await query(
        "insert into user (username, password, nickname) values (?, ?, ?)",
        [username, password, nickname]
    );

    // 添加成功
    if (res.affectedRows === 1) {
        ctx.body = {
            code: 201,
            message: "添加成功",
        };
    }
});

router.post("/login", async (ctx) => {
    //
    const { username, password } = ctx.request.body;
    // 根据用户名，查找用户
    const res = await query("select * from user where username = ?", [
        username,
    ]);
    if (res.length !== 1) {
        ctx.body = {
            code: 404,
            message: "用户",
        };
        return;
    }
    const user = res[0];
    // 密码是否匹配
    if (user.password !== password) {
        ctx.body = {
            code: 400,
            message: "用户密码不匹配",
        };
        return;
    }

    // 去除敏感字段
    delete user.password;

    // 服务器来生成 token，保证客户端无法篡改
    // 从数据库查询出来的对象都是类的实例
    // console.log(user);
    // console.log({ ...user });
    const token = genToken({ ...user });
    // 登录成功
    ctx.body = {
        code: 200,
        data: {
            token,
            user,
        },
        message: "登录成功",
    };
});

// app.use 加载一个中间件
// bodyparser() 中间件：解析请求体的
app.use(bodyparser());
// 加载身份认证中间件
app.use(auth());
// 加载路由表的
app.use(router.routes());

app.listen(32432, () => {
    console.log("服务已启动");
});
